/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.icee.myth.common;

import java.net.InetSocketAddress;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;

/**
 *	抽象服务器类
 * @author liuxianke
 */
public abstract class AbstractServer implements Server {

	private int port; // Server的端口地址

	private ServerBootstrap bootstrap;
	private Channel bindChannel = null;

	public AbstractServer() {
	}

	/**
	 * 使用帮助类ServerBootstrap准备启动网络服务
	 * 
	 * @param port
	 *            服务的端口
	 * @param pipelineFactory
	 *            Netty 通讯管道工厂
	 */
	public void init(int port, ChannelPipelineFactory pipelineFactory) {
		this.port = port;
		
		final Executor bossExecutor = Executors.newCachedThreadPool();
		final Executor workerExecutor = Executors.newCachedThreadPool();
		// Start server with Nb of active threads = 2*NB CPU + 1 as maximum.
		final int workerCount = Runtime.getRuntime().availableProcessors() * 2 + 1;

		// Channel不是直接被创建的，而是通过ChannelFactory来创建		
		ChannelFactory factory = new NioServerSocketChannelFactory(bossExecutor, workerExecutor, workerCount);

		// Configure the server.
		bootstrap = new ServerBootstrap(factory);

		bootstrap.setPipelineFactory(pipelineFactory);

		bootstrap.setOption("child.tcpNoDelay", true);	// 无延迟
		bootstrap.setOption("child.keepAlive", true);	// 保持存活
		bootstrap.setOption("reuseAddress ", true);		// 重复利用地址
	}

	@Override
	public void startServer() {
		// Bind and startOnlyOnce to accept incoming connections.
		bindChannel = bootstrap.bind(new InetSocketAddress(port));
	}

	@Override
	public void closeServer() {
		if (bindChannel != null) {
			bindChannel.close();
		}
	}
}
